package com.github.scr.hashmap.collections;

import java.io.DataOutput;
import java.io.IOException;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;

import com.github.scr.hashmap.Constants;
import com.github.scr.hashmap.collections.IntBufferCollection.BufferIterator;
import com.unbiz.common.collection.Iterators;

/**
 * Created by scr on 7/2/15. 存储对象的引用,int为values的offset
 */
public class ReferenceCollection implements IndexedCollection<Object> {
   
    private final IntBuffer BUFFER;
    private final Object[] values; //reference table
   
    @Override
    public Object get(int index) {
    	if(BUFFER==null) return values[index];
        int poiter = BUFFER.get(index);
        return values[poiter];
    }

  
    @Override
    public void writeOutput( DataOutput dataOutput) throws IOException {
        dataOutput.writeInt(Constants.MAGIC);
        dataOutput.writeInt(Constants.VERSION);
        if(BUFFER!=null){
        	 int size = BUFFER.remaining();
             dataOutput.writeInt(size);
             for (int i = 0; i < size; ++i) {
                 dataOutput.writeInt(BUFFER.get(i));
             }
        }       
    }

    public class BufferIterator implements Iterator<Object> {
    	private int cur = 0;
        private final IntBuffer BUFFER;

        public BufferIterator( IntBuffer buffer) {
        	if(buffer!=null)
        		BUFFER = buffer.duplicate();
        	else
        		BUFFER = null;
        }

        @Override
        public boolean hasNext() {
        	if(BUFFER==null) return cur < size();
            return BUFFER.hasRemaining();
        }
       
        @Override
        public Object next() {
        	if(BUFFER==null) return values[cur++];
            return values[BUFFER.get()];            
        }
    }
    
    /**
     * 集合是values的子集，元素存放在ints
     * @param ints
     * @param values
     */
    public ReferenceCollection(IntBuffer ints, Object[] values) {
        BUFFER = ints;
        this.values = values;
    }
    
    /**
     * 由values直接生成的集合
     * @param values
     */
    public ReferenceCollection(Object[] values) {
        BUFFER = null;
        this.values = values;
    }

    @Override
    public int size() {
    	if(BUFFER==null) return values.length;
        return BUFFER.capacity();
    }

    @Override
    public boolean isEmpty() {
    	if(BUFFER==null) return values.length==0;
        return BUFFER.capacity() == 0;
    }

    @Override
    public boolean contains( Object o) {
        if (!(o instanceof Integer)) {
            return false;
        }
        Integer oInteger = (Integer) o;
        return Iterators.contains(iterator(), oInteger);
    }

   
    @Override
    public Iterator<Object> iterator() {
        return new BufferIterator(BUFFER);
    }

   
    @Override
    public Object[] toArray() {       
        return values;
    }

   
    @Override
    public <T> T[] toArray( T[] a) {
        int size = size();
        if (a.length < size) {
            a = Arrays.copyOf(a, size);
        }
        for (int i = 0; i < size; ++i) {
            @SuppressWarnings("unchecked")
            T t = (T) values[BUFFER.get(i)];
            a[i] = t;
        }
        return a;
    }

    @Override
    public boolean add(Object integer) {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean remove( Object o) {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean containsAll( Collection<?> c) {
        for (Object o : c) {
            if (!contains(o)) {
                return false;
            }
        }
        return true;
    }

    @Override
    public boolean addAll( Collection<?> c) {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean removeAll( Collection<?> c) {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean retainAll( Collection<?> c) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void clear() {
        throw new UnsupportedOperationException();
    }

    @Override
    public int getInt(int index) {
    	if(BUFFER==null) return index;
        return BUFFER.get(index);
    }
}